#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "network.h"

NetWork* open_network(char c_or_s,int type,char* ip,uint16_t port)
{
	NetWork* nw = malloc(sizeof(NetWork));
	if(NULL == nw)
	{
		perror("network malloc");
		return NULL;
	}
	
	nw->type = type;
	nw->fd = socket(AF_INET,type,0);
	if(0 > nw->fd)
	{
		perror("network socket");
		free(nw);
		return NULL;
	}

	nw->addr.sin_family = AF_INET;
	nw->addr.sin_port = htons(port);
	nw->addr.sin_addr.s_addr = inet_addr(ip);
	nw->len = sizeof(nw->addr);
	
	if('s' == c_or_s)
	{
		if(bind(nw->fd,(SP)&nw->addr,nw->len))
		{
			perror("network bind");
			free(nw);
			return NULL;
		}

		if(SOCK_STREAM == type && listen(nw->fd,50))
		{
			perror("network listen");
			free(nw);
			return NULL;
		}
	}
	else if('c' == c_or_s && SOCK_STREAM == type)
	{
		if(connect(nw->fd,(SP)&nw->addr,nw->len))
		{
			perror("network connect");
			free(nw);
			return NULL;
		}
	}

	return nw;
}

size_t nrecv(NetWork* nw,void* ptr,size_t len)
{
	if(SOCK_STREAM == nw->type)
	{
		return recv(nw->fd,ptr,len,0);
	}
	else if(SOCK_DGRAM == nw->type)
	{
		return recvfrom(nw->fd,ptr,len,0,(SP)&nw->addr,&nw->len);
	}
	return -1;
}

size_t nsend(NetWork* nw,void* ptr,size_t len)
{
	if(SOCK_STREAM == nw->type)
	{
		return send(nw->fd,ptr,len,0);
	}
	else if(SOCK_DGRAM == nw->type)
	{
		return sendto(nw->fd,ptr,len,0,(SP)&nw->addr,nw->len);
	}
	return -1;
}

int close_network(NetWork* nw)
{
	perror("close_network");
	int ret = close(nw->fd);
	free(nw);
	return ret;
}
